import { Container } from 'inversify'
import { User } from './modules/user/user.controller'
import { UserServices } from './modules/user/user.services'
import { Post } from './modules/post/post.controller'
import { PostServices } from './modules/post/post.services'

// 温馨提示：
// 如遇报错 块“"@prisma/client"”没有导出的成员“PrismaClient”， 可运行 "prisma generate " 命令修复
import { PrismaClient } from '@prisma/client'
import { DB } from './db'
import { JWT } from './jwt'

/**
 * ## App 容器注入
 * @param container 容器，在 main.ts 中引用类时传入
 * @injObjList 中放置需要注入的对象，该类会自动进行注入
 * @injPlantList 中放置需要工厂注入的对象，该类会自动进行注入
 */

export class AppContainerInj {
  container: Container

  /** 注入对象列表 */
  injObjList: any[] = [User, UserServices, Post, PostServices, DB, JWT]

  /**
   * ### 注入工厂对象列表
   * - 元素格式为： {obj: [注入对象], name: 名称 }
   */
  injPlantList: any[] = [
    { obj: PrismaClient, name: 'prisma' }
  ]

  constructor(container: Container) {
    this.container = container

    // 执行注入
    this.injection(this.injObjList)
    this.injectPlant(this.injPlantList)
  }

  /**
   * ### 普通注入
   * @param InjObjList 注入对象列表
   * - 根据注入对象列表自动循环注入
   */
  private injection(InjObjList: any[]) {
    InjObjList.forEach(item => this.container.bind(item).toSelf())
  }

  /**
   * ### 注入工厂
   * @param InjPlantList 注入对象列表
   * - 根据注入对象列表自动循环注入
   */
  private injectPlant(InjPlantList: any[]) {

    InjPlantList.forEach(item => this.container.bind(item.name).toFactory(() => {
      return () => {
        return new item.obj()
      }
    }))
  }
}